package com.yuecai.modules.security.security;

import com.yuecai.modules.security.JwtUserDto;
import com.yuecai.modules.security.service.SmsCodeAuthenticationToken;
import com.yuecai.modules.yc_coupon.service.YcCouponService;
import com.yuecai.modules.yc_order.service.utils.MakeOrderNum;
import com.yuecai.modules.yc_user.domain.YcUser;
import com.yuecai.modules.yc_user.repository.YcUserRepository;
import com.yuecai.modules.yc_user.service.YcUserService;
import com.yuecai.modules.yc_user.service.dto.YcUserDto;
import com.yuecai.modules.yc_user.service.mapstruct.YcUserMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.InternalAuthenticationServiceException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.util.Optional;

@Slf4j
@Component
@RequiredArgsConstructor
public class SmsCodeProvider implements AuthenticationProvider {


    @Autowired
    private UserDetailsService userDetailsService;



    @Autowired
    private PasswordEncoder passwordEncoder;


    @Autowired
    private YcUserRepository ycUserRepository;


    @Autowired
    private YcUserMapper ycUserMapper;


    @Autowired
    private YcUserService ycUserService;



    @Autowired
    private YcCouponService ycCouponService;


    /**
     * 认证
     */
    @Override
    @Transactional
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        Object credentials = authentication.getCredentials();
        String principal = (String)authentication.getPrincipal();

        //获取过滤器封装的token信息
        SmsCodeAuthenticationToken authenticationToken = (SmsCodeAuthenticationToken) authentication;
        YcUser byName = ycUserService.findByName(principal);
        UserDetails userDetails = null;
        String referralCode = (String) authenticationToken.getReferralCode();
        if (byName==null){
            YcUser ycUser = new YcUser();
            ycUser.setPhone(principal);
            ycUser.setLevel(1);
            ycUser.setState(0);
            ycUser.setImgUrl("https://www.baidu.com/link?url=i5xWchgwzH0M88NISZxMIhZvdAAYn_2LQRKEWHPmrjTYEamOexvLOa9fd2ct5TT8r04uZ1qHCkk83mkHFtBTZ83s8a0hm9LZNtTsiM1eu88g9ylON8WFWyUQckJm8cmr7fSLhKevyRC8mlAkKfJ-hRIC4gegTCiczmGtu5Bbxtom_riqMP9wBC3DJk_2GFE0kP5eLrKgCRwXFIXEsG_Y-_OIbj3xZmtI");
            ycUser.setPassword(passwordEncoder.encode("123456"));
            ycUser.setReferralCode(MakeOrderNum.referralCode());
            if (StringUtils.isNotBlank(referralCode)){
                Optional<YcUser> byReferralCode = ycUserRepository.findByReferralCode(referralCode);
                if (byReferralCode.isPresent()){
                    ycUser.setPid(byReferralCode.get().getId());
                }
            }

            YcUser save = ycUserRepository.save(ycUser);
            if (save!=null){
                ycCouponService.register(save.getId(),save.getPid());
            }
            ycUser.setNickName("悦采"+save.getId());
            YcUser save1 = ycUserRepository.save(ycUser);
            YcUserDto dto = ycUserMapper.toDto(save1);
            userDetails = new JwtUserDto(dto,null);
        }else {
            //获取用户信息（数据库认证）
            userDetails = userDetailsService.loadUserByUsername(principal);
        }
        //不通过
        if (userDetails == null) {
            throw new InternalAuthenticationServiceException("Unable to obtain user information");
        }
        //通过
        SmsCodeAuthenticationToken authenticationResult = new SmsCodeAuthenticationToken(userDetails,referralCode, userDetails.getAuthorities());
        authenticationResult.setDetails(authenticationToken.getDetails());
        return authenticationResult;
    }

    /**
     * 根据token类型，来判断使用哪个Provider
     */
    @Override
    public boolean supports(Class<?> authentication) {
        return SmsCodeAuthenticationToken.class.isAssignableFrom(authentication);
    }
}